package db

import (
	"encoding/json"
	"errors"
	"reflect"
	"strconv"
	"strings"

	"gitee.com/zhangycsz/goben"
)

// op
// = <> > >= < <= [NOT]LIKE [NOT]IN [NOT]BETWEEN [NOT]NULL

type whereFiled struct {
	Field     string        // name = <> > >= < <= [NOT]LIKE [NOT]IN [NOT]BETWEEN [NOT]NULL
	Val       []interface{} //值,字符串，或者切片
	Condition string        //条件 ,or或者and,默认是and
}

// 操作表的链式
type IDbTale struct {
	field       string                //查找的字段
	order       string                //排序字段
	page        int                   //当前页
	limit       int                   //每页显示
	tableName   string                //表名，不带前缀
	distinct    string                //是否去重
	prefix      string                //前缀，比如boss_
	join        string                //连接语句，比如left join xxx on xxx=xxx
	alias       string                //表别名
	where       []whereFiled          //查询条件
	isShow      int                   //显示总条数
	isOptionSql bool                  //是否隐藏sql语句,默认是回调sql的操作，如果不需要去回调，设置为false
	isSelectSql bool                  //是否输出查询的sql语句，默认是false,如果要输出，设置为true,输出在回调中
	isVerify    bool                  //是否校验数据类型合法性，默认是false,如果要校验设置为true
	fieldList   map[string]tableField //校验数据类型合法性
}

// 创建数据模型,table 表名或者结构体,或者结构体指针
// taleName 或者&struct{} 或者 *struct{}
func NewTable(table interface{}) *IDbTale {
	iDbTale := &IDbTale{where: make([]whereFiled, 0), fieldList: make(map[string]tableField), isOptionSql: goben.NewDb().IDbConf.IsShowOptionSql, isSelectSql: goben.NewDb().IDbConf.IsShowSelectSql}
	iDbTale.tableName = goben.GetTable(table)
	iDbTale.prefix = goben.NewDb().IDbConf.Prefix
	iDbTale.fieldList = getTableVerifyField(table)
	return iDbTale
}

// 设置表名称，
// taleName 或者&struct{} 或者 *struct{}
func (ths *IDbTale) SetTable(table interface{}) *IDbTale {
	talbeName := goben.GetTable(table)
	ths.tableName = talbeName
	return ths
}

// 返回表面，有可能是需要前缀
func (ths *IDbTale) GetTable() string {
	tableName := ths.prefix + ths.tableName
	if ths.alias != "" {
		tableName = tableName + " as " + ths.alias
	}
	return tableName
}

// 设置是否输出sql语句，主要用于记录事件，操作为add,edit,del
// true(默认):输入sql语句日志到数据库，false 否则不输出
func (ths *IDbTale) SetOptionSql(isHide bool) *IDbTale {
	ths.isOptionSql = isHide
	return ths
}

// 设置是否输出sql语句，主要用于记录事件，查询操作，
// true输入sql语句日志到数据库，false(默认) 否则不输出
func (ths *IDbTale) SetSelectSql(isSelect bool) *IDbTale {
	ths.isSelectSql = isSelect
	return ths
}

// 在新增，编辑数据的，是否需要强制校验数据
func (ths *IDbTale) SetIsVerify(isVerify bool) *IDbTale {
	ths.isVerify = isVerify
	return ths
}

// 主要是做回调的，对sql语句监控,主要是新增(insert)，删除(delete)，更新(update)
// 新增(insert)，删除(delete)，更新(update)
func (ths *IDbTale) callBack(option, sql string, datalist []interface{}) {
	//fmt.Println("callBack isHide:", ths.isHide, ";option=", option, ";sql:", sql, ";datalist:", datalist)
	if !ths.isOptionSql {
		return
	}
	if goben.NewDb().IDbConf.SqlOptionCallBack == nil {
		return
	}
	goben.NewDb().IDbConf.SqlOptionCallBack(option, ths.prefix+ths.tableName, sql, datalist)
}

// 回调输出
// 查询 select
func (ths *IDbTale) callSelect(sql string, datalist []interface{}) {
	//fmt.Println("callBack callSelect isSelect:", ths.isSelect, ";option=select;sql:", sql, ";datalist=", datalist)
	if !ths.isSelectSql {
		return
	}
	if goben.NewDb().IDbConf.SqlOptionCallBack == nil {
		return
	}
	goben.NewDb().IDbConf.SqlOptionCallBack("select", ths.prefix+ths.tableName, sql, datalist)
}

// 所有的错误信息记录
func (ths *IDbTale) error(sql string, datalist []interface{}, option string, err error) {
	//fmt.Println("Error sql:", sql, ";datalist:", datalist, ";option=", option, ";err=", err)
	if goben.NewDb().IDbConf.SqlErrorCallBack == nil {
		return
	}
	goben.NewDb().IDbConf.SqlErrorCallBack(sql, datalist, option, err)
}

// 设置表名，并且获取到表的名称，主要是判断是否有表前缀
func (ths *IDbTale) GetTableName(table interface{}) string {
	ths.tableName = goben.GetTable(table)
	tableName := ths.prefix + ths.tableName
	return tableName
}

// 设置表前缀,默认是继承全局配置的表前缀
func (ths *IDbTale) SetPrefix(prefix string) *IDbTale {
	ths.prefix = prefix
	return ths
}

// 表得到前缀
func (ths *IDbTale) GetPrefix() string {
	return ths.prefix
}

// 设置显示的字段
func (ths *IDbTale) SetField(field string) *IDbTale {
	ths.field = field
	return ths
}

// 设置排序
// id asc(升序) 或者id desc(降序)
func (ths *IDbTale) SetOrder(order string) *IDbTale {
	if order == "" {
		return ths
	}
	ths.order = "order by " + order
	return ths
}

// 设置升序排序，order:字段名
func (ths *IDbTale) SetAsc(filed string) *IDbTale {
	ths.order = "order by " + filed + " asc"
	return ths
}

// 设置降序排序，order:字段名
func (ths *IDbTale) SetDesc(filed string) *IDbTale {
	ths.order = "order by " + filed + " desc"
	return ths
}

// 设置分页，page:当前页面,默认1，limit:每页多少条数据,支持string者int类型
func (ths *IDbTale) SetPage(page, limit interface{}) *IDbTale {
	if page == nil || limit == nil {
		return ths
	}
	switch p := page.(type) {
	case int:
		//if p <= 0 {
		//	page = 1
		//}
		ths.page = page.(int)
	case string:
		_page, _ := strconv.Atoi(p)
		if _page <= 0 {
			_page = 1
		}
		ths.page = _page

	}
	//fmt.Println("page=", ths.page)
	switch l := limit.(type) {
	case int:
		if l <= 0 {
			limit = 10
		}
		ths.limit = limit.(int)
	case string:
		_limit, _ := strconv.Atoi(l)
		if _limit <= 0 {
			_limit = 10
		}
		ths.limit = _limit
	}

	return ths
}

// 去重字段,field:字段
func (ths *IDbTale) SetDistinct(field string) *IDbTale {
	ths.distinct = "DISTINCT `" + field + "`"
	return ths
}

// 设置查询条件,全部是and
// map查询,
// --   map[name =?]=interface{} 格式的查询条件
//--     map["id in (?,?)"] = [1,2]
// name = ? and age > ?,参数
// --  name ? ,参数，
// 如果是查name = (select * from user)
// --		    filed, list := db.NewTable("admin").SetField("name").And(param).SelectSql()
// --	        db.NewTable("admin").And("name = ("+filed+")", list).Select()
// 查询 (name =? and age > ?) or(name =? and age > ?)
// --			db.NewTable("admin").And(db.NewTable("").And(param).WhereSql()).Or("user = ?", "adminddd").Select()
// 查询 结构体查询--不建议，因为结构体存在默认参数
// join查询 --未实现
//--		db.NewTable("admin").Join(" user on admin.id = user.id","left").Select()

func (ths *IDbTale) _where(condition string, fieldList ...interface{}) *IDbTale {
	for i := 0; i < len(fieldList); i++ {
		ths.__where(condition, fieldList[i])
	}
	return ths
}

// 字段 in(?,?,..) [...]在数据之间
// 字段 BETWEEN ? and ?
// 具体每条数据分析类型
func (ths *IDbTale) __where(condition string, field interface{}) *IDbTale {

	rv := reflect.ValueOf(field)
	switch rv.Kind() {
	case reflect.Slice:
		vwhere := whereFiled{Field: "", Val: make([]interface{}, 0), Condition: condition}
		for i := 0; i < rv.Len(); i++ {
			vv := rv.Index(i)
			rvv := reflect.ValueOf(vv.Interface())

			if i == 0 {
				switch rvv.Kind() {
				case reflect.String:
					vwhere.Field = vv.Interface().(string)
				case reflect.Map:
					ths.__whereMap(condition, vv.Interface())
				default:
					panic("查询数据 不支持的类型" + rvv.Kind().String())
				}
			} else {

				switch rvv.Kind() {
				case reflect.Slice:
					//fmt.Println("查询语句里面 数据是切片")
					//如果是切片，需要分开处理
					for j := 0; j < rvv.Len(); j++ {
						vvv := rvv.Index(j)
						vwhere.Val = append(vwhere.Val, vvv.Interface())
					}
				default:
					vwhere.Val = append(vwhere.Val, vv.Interface())
				}

			}
		}

		if vwhere.Field != "" {
			ths.where = append(ths.where, vwhere)
		}
	case reflect.Map:
		ths.__whereMap(condition, rv.Interface())
	default:
		panic("查询数据 不支持的类型" + rv.Kind().String())
	}

	return ths

}

func (ths *IDbTale) __whereMap(condition string, field interface{}) *IDbTale {

	rv := reflect.ValueOf(field)
	for _, key := range rv.MapKeys() {
		keyString := key.String()
		value := rv.MapIndex(key)
		if keyString == "" {
			continue
		}

		vtype := reflect.ValueOf(value.Interface()) //需要判断是不是切片类型，如果是切片需要分开处理

		switch vtype.Kind() {
		case reflect.Slice:
			//如果是切片，需要分开处理
			vwhere := whereFiled{Field: keyString, Val: make([]interface{}, 0), Condition: condition}
			for j := 0; j < vtype.Len(); j++ {
				vvv := vtype.Index(j)
				vwhere.Val = append(vwhere.Val, vvv.Interface())
			}
			ths.where = append(ths.where, vwhere)
		default:
			vwhere := whereFiled{Field: keyString, Val: make([]interface{}, 0), Condition: condition}
			vwhere.Val = append(vwhere.Val, value.Interface())
			ths.where = append(ths.where, vwhere)
		}

		//vwhere := whereFiled{Field: keyString, Val: make([]interface{}, 0), Condition: condition}
		//vwhere.Val = append(vwhere.Val, value.Interface())
		//ths.where = append(ths.where, vwhere)
	}

	return ths
}

// 使用and
func (ths *IDbTale) And(field ...interface{}) *IDbTale {
	ths._where("AND", field)
	return ths
}

// 使用and
func (ths *IDbTale) Where(field ...interface{}) *IDbTale {
	ths._where("AND", field)
	return ths
}

// 使用or
func (ths *IDbTale) Or(field ...interface{}) *IDbTale {
	ths._where("or", field)
	return ths
}

// 统一搜索的字段
type WhereMap struct {
	Op  string      //操作符 = <> > >= < <= [NOT]LIKE [NOT]IN [NOT]BETWEEN [NOT]NULL
	Val interface{} //值,字符串，或者切片
}

// 表别名，主要是join查询的时候用
func (ths *IDbTale) Alias(alias string) *IDbTale {
	ths.alias = alias
	return ths
}

// 跨表查询,join_talbe:表名，condition:条件,left join right join inner join
// table 表 ，不需要表前缀 as b , left json
// alias 别名，类似 table as b
// condition :条件,a.id=b.id
// left:方向，默认 left join
func (ths *IDbTale) Join(table, alias, condition, left string) *IDbTale {
	if left == "" {
		left = " LEFT JOIN"
	}
	join_table := ths.prefix + table + " as " + alias
	ths.join += left + " " + join_table + " on " + condition
	return ths
}

// 获取数据
func (ths *IDbTale) Select() (result []byte, err error) {
	result = make([]byte, 0)
	db := goben.NewDb().GetRDB()
	err = db.Ping()
	if err != nil {
		ths.error("", nil, "ping", err)
		return
	}
	sql, datalist := ths.SelectSql()
	ths.callSelect(sql, datalist)
	smt, err := db.Prepare(sql)
	if err != nil {
		ths.error(sql, datalist, "Select Prepare", err)
		return
	}
	defer smt.Close()

	rows, err := smt.Query(datalist...)
	if err != nil {
		ths.error(sql, datalist, "Select Query", err)
		return
	}
	defer rows.Close()
	resultColumns, err := goben.GetTableColumnsTypeRow(rows)
	if err != nil {
		ths.error(sql, datalist, "Select resultColumns", err)
		return
	}
	if len(resultColumns) > 0 {
		if ths.isShow == 1 {
			result, err = json.Marshal(resultColumns[0])
			if err != nil {
				ths.error(sql, datalist, "Select Marshal", err)
			}

			return
		}
		result, err = json.Marshal(resultColumns)
		if err != nil {
			ths.error(sql, datalist, "Select Marshal", err)
		}
		return
	}
	return
}

// 显示总条数据
func (ths *IDbTale) Total() (total int64, err error) {
	db := goben.NewDb().GetRDB()
	err = db.Ping()
	if err != nil {
		ths.error("", nil, "ping", err)
		return
	}
	ths.field = "COUNT(*) as total"
	sql, datalist := ths.SelectSql()

	ths.callSelect(sql, datalist)
	smt, err := db.Prepare(sql)
	if err != nil {
		ths.error(sql, datalist, "Total Prepare", err)
		return
	}
	defer smt.Close()

	rows, err := smt.Query(datalist...)
	if err != nil {
		ths.error(sql, datalist, "Total Query", err)
		return
	}
	defer rows.Close()
	if rows.Next() {
		err = rows.Scan(&total)
		if err != nil {
			ths.error(sql, datalist, "Total Scan", err)
		}
	} else {
		return 0, nil
	}

	return
}

// 返回操作符合
// = <> > >= < <= [NOT]LIKE [NOT]IN [NOT]BETWEEN [NOT]NULL
func (ths *IDbTale) getOperation(op, vField string) (result string, resultVal interface{}) {
	op = strings.ReplaceAll(op, " ", "")
	switch strings.ToUpper(op) {
	case "=":
		result = "= ?"
	case "<>":
		result = "<> ?"
	case ">":
		result = "> ?"
	case "<":
		result = "< ?"
	case ">=":
		result = ">= ?"
	case "<=":
		result = "<= ?"
	case "NOTLIKE":
		result = "NOT LIKE ( " + vField + ") "
	case "LIKE":
		result = "LIKE ( " + vField + ") "
	case "IN":
		result = "IN ( " + vField + " )"
	case "NOTIN":
		result = "NOT IN (  " + vField + " )"
	case "BETWEEN":
		result = "BETWEEN ? AND ?"
	case "NOTBETWEEN":
		result = "NOT BETWEEN ? AND ?"
	case "NOTNULL":
		result = "IS NOT NULL"
	case "NULL":
		result = "IS NULL"
	default:
		panic("表达式不支持 " + op)
	}
	return
}

// 是否需要增加别名访问
func (ths *IDbTale) getAlias(field string) string {
	if ths.alias != "" {
		return ths.alias + "." + field
	}
	return field
}

// 把where条件生成sql语句，
// 返回field:字段位置符合,values:值的位置符号,DataList:需要添加的数据列表
func (ths *IDbTale) WhereSql() (field string, DataList []interface{}) {
	DataList = make([]interface{}, 0)

	for _, v := range ths.where {
		if field != "" {
			field += v.Condition + " "
		}
		field += v.Field + " "

		DataList = append(DataList, v.Val...)
	}
	if field != "" {
		field = "(" + field + ")"
	}
	return
}

// 把目前的sql生成出来
// sql:操作的sql,qurylist:需要添加的数据列表
func (ths *IDbTale) SelectSql() (sql string, qurylist []interface{}) {
	sql = "select "

	if ths.distinct != "" {
		sql += ths.distinct + " "
	} else if ths.field != "" {
		sql += ths.field + " "
	} else {
		sql += "* "
	}
	sql += "from " + ths.GetTable() + " "
	sqlWhere, qurylist := ths.WhereSql()
	if ths.join != "" {
		sql += ths.join + " "
	}
	if sqlWhere != "" {
		sql += "where " + sqlWhere + " "
	}
	if ths.order != "" {
		sql += ths.order + " "
	}
	if ths.page > 0 {
		_page := (ths.page - 1) * ths.limit
		if _page < 0 {
			_page = 0
		}
		sql += "limit " + strconv.Itoa(_page) + "," + strconv.Itoa(ths.limit) + " "
	} else {
		if ths.isShow == 1 { //避免显示全部数据，但是还是有分页限制的，所以这里需要加上limit 1限制
			sql += "limit 1"
		}
	}

	//fmt.Println("sql:", sql)
	//fmt.Println("qurylist:", qurylist)
	return
}

// 返回更新的sql语句，
// paramlist 更新的数据
// values:值的位置符号,execValList:需要添加的数据列表
func (ths *IDbTale) _updateSql(paramlist map[string]interface{}) (sql string, qurylist []interface{}) {
	qurylist = make([]interface{}, 0)
	filed_set := ""
	for key, val := range paramlist {
		filed_set += ",`" + key + "`= ?"
		qurylist = append(qurylist, val)
	}
	if filed_set != "" {
		filed_set = filed_set[1:]
	}
	field_where, list := ths.WhereSql()
	qurylist = append(qurylist, list...)
	sql = "UPDATE `" + ths.GetTable() + "` SET " + filed_set + " WHERE " + field_where
	return
}

// 返回插入的sql语句，field:字段位置符合,values:值的位置符号,execValList:需要添加的数据列表
func (ths *IDbTale) _insertSql(paramlist map[string]interface{}) (sql string, execList []interface{}) {
	field := ""
	values := ""
	execList = make([]interface{}, 0)
	for key, val := range paramlist {
		field += ",`" + key + "`"
		values += ",?"
		execList = append(execList, val)
	}
	if field != "" {
		field = field[1:]
	}
	if values != "" {
		values = values[1:]
	}
	if field == "" {
		return "", execList
	}
	sql = "INSERT INTO `" + ths.GetTable() + "` (" + field + ") VALUES (" + values + ")"
	return
}

// 删除的sql语句，sql:操作的sql,qurylist:需要添加的数据列表
func (ths *IDbTale) DeleteSql() (sql string, qurylist []interface{}) {
	field, qurylist := ths.WhereSql()
	sql = "DELETE FROM `" + ths.GetTable() + "` WHERE " + field
	return
}

// data:支持map[string]interface{}和struct{}
func (ths *IDbTale) _setData(data interface{}) map[string]interface{} {
	result := make(map[string]interface{}, 0)
	objType := reflect.TypeOf(data)
	switch objType.Kind() {
	case reflect.Ptr: //结构体的指针
		objValue := reflect.ValueOf(data).Elem()
		for i := 0; i < objValue.NumField(); i++ {
			fieldType := objValue.Type().Field(i)
			fildValue := objValue.Field(i)
			result[fieldType.Name] = fildValue.Interface()
		}
	case reflect.Struct: //结构体
		objValue := reflect.ValueOf(data)
		for i := 0; i < objType.NumField(); i++ {
			fieldType := objType.Field(i)
			fildValue := objValue.Field(i)
			result[fieldType.Name] = fildValue.Interface()
		}
	case reflect.Map: //map[string]interface{}
		objValue := reflect.ValueOf(data)
		for _, key := range objValue.MapKeys() {
			keyString := key.String()
			value := objValue.MapIndex(key)
			result[keyString] = value.Interface()
		}
	default:
		panic("不支持的类型" + objType.Kind().String())
	}

	return result
}

// 插入数据
// data:支持map[string]interface{}和struct{}
func (ths *IDbTale) Insert(data interface{}) (id int64, err error) {
	db := goben.NewDb().GetWDB()
	if db.Ping() != nil {
		ths.error("", nil, "Insert Ping", err)
		return 0, errors.New(db.Ping().Error())
	}
	param := ths._setData(data)
	if ths.isVerify { //校验数据合法性
		err = checkAddTableFieldData(ths.fieldList, param)
		if err != nil {
			return 0, err
		}
	}
	sql, vallist := ths._insertSql(param)
	if sql == "" {
		err = errors.New("数据为空")
		ths.error(sql, vallist, "Insert set data ", err)
		return id, err
	}
	ths.callBack("insert", sql, vallist)

	smt, err := db.Prepare(sql)
	if err != nil {
		ths.error(sql, vallist, "Insert Prepare ", err)
		return id, err
	}
	defer smt.Close()

	result, err := db.Exec(sql, vallist...)
	if err != nil {
		ths.error(sql, vallist, "Insert Exec ", err)
		return id, err
	}
	id, err = result.LastInsertId()
	total, err := result.RowsAffected()
	if err != nil {
		ths.error(sql, vallist, "Insert LastInsertId ", err)
		return id, err
	}
	if total == 0 {
		return id, errors.New("无数据更新")
	}
	return id, nil
}

// 更新
// 需要先实现where
// data:支持map[string]interface{}和struct{}
func (ths *IDbTale) Update(data interface{}) (err error) {
	db := goben.NewDb().GetWDB()
	err = db.Ping()
	if err != nil {
		ths.error("", nil, "update ping", err)
		return
	}
	param := ths._setData(data)
	if ths.isVerify { //校验数据合法性
		err = checkEditTableFieldData(ths.fieldList, param)
		if err != nil {
			return err
		}
	}
	sql, qurylist := ths._updateSql(param)
	ths.callBack("update", sql, qurylist)
	smt, err := db.Prepare(sql)
	if err != nil {
		ths.error(sql, qurylist, "update Prepare", err)
		return err
	}
	defer smt.Close()
	_, err = smt.Exec(qurylist...)
	if err != nil {
		ths.error("", nil, "update Exec", err)
		return err
	}

	return nil
}

// 删除数据
func (ths *IDbTale) Delete() (err error) {
	db := goben.NewDb().GetWDB()
	err = db.Ping()
	if err != nil {
		ths.error("", nil, "Delete ping", err)
		return err
	}
	sql, vallist := ths.DeleteSql()
	ths.callBack("delete", sql, vallist)
	smt, err := db.Prepare(sql)
	if err != nil {
		ths.error("", nil, "Delete Prepare", err)
		return err
	}
	defer smt.Close()

	result, err := smt.Exec(vallist...)
	if err != nil {
		ths.error(sql, vallist, "Delete Exec", err)
		return err
	}
	total, err := result.RowsAffected()
	if err != nil {
		ths.error(sql, vallist, "Delete RowsAffected", err)
		return err
	}
	if total == 0 {
		return errors.New("无数据可删除")
	}
	return nil
}

// 新增数据
func (ths *IDbTale) Add(data map[string]interface{}) (id int64, err error) {
	db := goben.NewDb().GetWDB()
	err = db.Ping()
	if err != nil {
		ths.error("", nil, "Add ping", err)
		return
	}

	if ths.isVerify { //校验数据合法性
		err = checkAddTableFieldData(ths.fieldList, data)
		if err != nil {
			return 0, err
		}
	}
	sql, vallist := ths._insertSql(data)
	if sql == "" {
		err = errors.New("添加的数据为空")
		ths.error(sql, vallist, "Add add", err)
		return id, err
	}

	ths.callBack("insert", sql, vallist)
	smt, err := db.Prepare(sql)
	if err != nil {
		ths.error(sql, vallist, "Add Prepare", err)
		return id, err
	}
	defer smt.Close()

	result, err := db.Exec(sql, vallist...)
	if err != nil {
		ths.error(sql, vallist, "Add Exec", err)
		return id, err
	}
	id, err = result.LastInsertId()
	total, err := result.RowsAffected()
	if err != nil {
		ths.error(sql, vallist, "Add RowsAffected", err)
		return id, err
	}
	if total == 0 {
		return id, errors.New("无数据更新")
	}
	return id, nil
}

// 编辑数据
// maps[name=?] value[]
func (ths *IDbTale) Edit(maps map[string]interface{}, data map[string]interface{}) (err error) {
	db := goben.NewDb().GetWDB()
	err = db.Ping()
	if err != nil {
		ths.error("", nil, "Edit ping", err)
		return
	}
	if ths.isVerify { //校验数据合法性
		err = checkEditTableFieldData(ths.fieldList, data)
		if err != nil {
			return err
		}
	}
	ths._where("and", maps)
	sql, vallist := ths._updateSql(data)
	ths.callBack("update", sql, vallist)
	smt, err := db.Prepare(sql)
	if err != nil {
		ths.error(sql, vallist, "Edit Prepare", err)
		return err
	}
	defer smt.Close()

	result, err := smt.Exec(vallist)
	if err != nil {
		ths.error(sql, vallist, "Edit Exec", err)
		return err
	}
	total, err := result.RowsAffected()
	if err != nil {
		ths.error(sql, vallist, "Edit RowsAffected", err)
		return err
	}
	if total == 0 {
		return errors.New("无数据操作")
	}
	return nil

}

// 删除数据
// map[name =?] value[]
func (ths *IDbTale) Del(maps map[string]interface{}) (err error) {
	db := goben.NewDb().GetWDB()

	err = db.Ping()
	if err != nil {
		ths.error("", nil, "Del ping", err)
		return err
	}
	ths._where("and", maps)
	sql, vallist := ths.DeleteSql()
	ths.callBack("delete", sql, vallist)
	smt, err := db.Prepare(sql)
	if err != nil {
		ths.error(sql, vallist, "Del Prepare", err)
		return err
	}
	defer smt.Close()

	result, err := smt.Exec(vallist...)
	if err != nil {
		ths.error(sql, vallist, "Del Exec", err)
		return err
	}
	total, err := result.RowsAffected()
	if err != nil {
		ths.error(sql, vallist, "Del RowsAffected", err)
		return err
	}
	if total == 0 {
		return errors.New("无数据可删除")
	}
	return nil
}

// 获取单条数据,不要在and或者where 新增条件，否则会出错
func (ths *IDbTale) GetOne(maps map[string]interface{}) (result []byte, err error) {
	ths.isShow = 1
	return ths._where("and", maps).Select()
}

// 查询多条数据 不要在and或者where 新增条件，否则会出错
func (ths *IDbTale) GetAll(maps map[string]interface{}) (result []byte, err error) {
	return ths._where("and", maps).Select()
}
